/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package multiNyID.Interaksi;

import javax.media.j3d.Switch;
import javax.vecmath.Point2d;
import javax.vecmath.Point2i;
import javax.vecmath.Point3d;
import javax.vecmath.Point4d;
import multiNyID.MarkerModel.MarkerModelNyID;

/**
 * class OcclusionDetection
 *
 *
 * @author whe_green@yahoo.co.id
 * Analisis Metode Occlusion Based Pada Augmented Reality
 * Studi Kasus Interaksi dengan Objek Virtual Secara Realtime
 * Menggunakan Gerakan Tangan
 *
 * Institut Teknologi Telkom
 * Fakultas Informatika 2007
 * Bandung Indonesia
 *
 * nyargreen.wordpress.com
 */

public class DemoOcclusion implements InteraksiInterface{
        private Point4d batas;
        // maxX = batas.x
        // minX = batas.y
        // maxY = batas.Z
        // minY = batas.w

        //scale = 0.275
        //skala papancatur = scale/2 = 0,138
        //panjang sisi papancatur = 8 * 0,138
        //radius = panjang sisi / (2*ukuran marker + jarak marker)
        
        private Point2d ptr1,ptr2,pusatGrid;

        private Point2i ordinat = new Point2i();

        private final double radius = 0.18/1.415;  //  1 cm --> 0,01 jadi 32 cm = 0.32
//        private final double radius = 0.36/1.415;  //  1 cm --> 0,01 jadi 32 cm = 0.32
        private final double radiusPtr = 0.1/1.415;

        private boolean onAmbil;
        
    public DemoOcclusion() {
    }
    public void indikatorPointer(MarkerModelNyID grid,MarkerModelNyID ptr,StringBuffer stat) {

        if((grid==null)||(ptr==null)){
            System.out.println("null");
            return;
        }
        pusatGrid = konvPtr(grid.getPos());
        ptr1 = konvPtr(ptr.getPos());
//        Point3d jarak = grid.boundingBox();
        
        geserPointer(grid, stat);
    }
    public void indikatorPointer(MarkerModelNyID grid,MarkerModelNyID ptr1,
            MarkerModelNyID ptr2,StringBuffer stat) {

        if((ptr1==null)||(grid==null)){
            System.out.println("null");
            return;
        }
        pusatGrid = konvPtr(grid.getPos());
        this.ptr1 = konvPtr(ptr1.getPos());
//        Point3d jarak = grid.boundingBox();
        if(ptr2!=null){            
            this.ptr2 = konvPtr(ptr2.getPos());
        }
        geserPointer(grid, stat);
    }

    public void geserPointer(MarkerModelNyID grid, StringBuffer stat){

        batas = hitBatas(pusatGrid, radius); //bikin kotak seluas papan catur
        int ordX = translatePosisi(batas.getX(), batas.getZ(), ptr1.getX());
        ordX = (ordX-7)*-1;
        int ordY = translatePosisi(batas.getY(), batas.getW(), ptr1.getY());
        ordinat.setX(ordX);
        ordinat.setY(ordY);

        if (isOcclusion(ptr1, batas)){
            System.out.println("----------> OCCLUSION");
            stat.append("ordinat"+ordX+" - "+ordY+"--> OCCLUSION");
            if(ptr2==null)
            stat.append("pointer 2 null");
            System.out.println("ordinat( "+ordX+" )-( "+ordY+" )");
            //pointer
            grid.getPointer().setPosAkhir(ordinat.getX(), ordinat.getY());
            grid.getPointer().moveModel();
            grid.getPointer().getModel(ordinat.getX(), ordinat.getY()).switchOn(Switch.CHILD_ALL);
            //sisip
            if (ptr2!=null){
                geserBidak(grid, stat);
            }
        }

        else {
            System.out.println("----------> GA OCCLUSION");
            stat.append("GA OCCLUSION <-------");
            int a = grid.getPointer().getPosAwal().getX();
            int b = grid.getPointer().getPosAwal().getY();
//            grid.getPointer().sisiBawah(ordinat.getX(), ordinat.getY(),false); //jadi ijo
            grid.getPointer().getModel(a,b).switchOn(Switch.CHILD_NONE);
            //pointer
        }
    }
    public boolean isAmbilBidak(Point2d p, Point4d b){        
        return ((isOcclusion(p, b))==true) ? true : false;
    }
    public void geserBidak(MarkerModelNyID grid, StringBuffer stat){

        Point4d bts = hitBatas(ptr1,radiusPtr);
        if (isAmbilBidak(ptr2,bts)){ //kalo interaksi
            grid.getPointer().sisiBawah(ordinat.getX(), ordinat.getY(),true); //jadi merah
        }
        else{
            grid.getPointer().sisiBawah(ordinat.getX(), ordinat.getY(),false); //jadi ijo
        }
        if (!onAmbil){

            if (isAmbilBidak(ptr2,bts)&&(grid.getBidak().getModel(ordinat.getX(), ordinat.getY())!=null)){
                System.out.println("----------> ambil bidak");
                stat.append("--> ambil bidak");
                //
                onAmbil =true;
                grid.getBidak().setPosAwal(ordinat.getX(), ordinat.getY()); //pos awal = koord tempat ambil
//                bidak.moveModel(); // belum bisa pindahin model
                grid.getBidak().getModel(ordinat.getX(), ordinat.getY()).switchOn(Switch.CHILD_NONE);
                //bikin VOID penanda merah2 CODE
            }
            else{
                System.out.println("----------> ga ambil");
                stat.append("ga ambil <-------");
                //nothing
                onAmbil = false;
            }
        }else{
            if ((onAmbil)&&!isAmbilBidak(ptr2,bts)){ //pegang dan dilepas
                if (grid.getBidak().getModel(ordinat.getX(), ordinat.getY())==null){ //tujuannya kosong --> boleh
                    //pindah
                    System.out.println("----------> taruh bidak");
                    stat.append("--> taruh bidak");
                    grid.getBidak().setPosAkhir(ordinat.getX(), ordinat.getY());
                    grid.getBidak().moveModel();
                    grid.getBidak().getModel(ordinat.getX(), ordinat.getY()).switchOn(Switch.CHILD_ALL);
                    onAmbil=false;
//                    System.exit(0);
                }
                else{
                    //balikin ke tempat awal
                    System.out.println("----------> batal pindah");
                    stat.append("--> batal pindah");
                    onAmbil =false;
                    Point2i p = grid.getBidak().getPosAwal();
                    grid.getBidak().getModel(p.getX(),p.getY()).switchOn(Switch.CHILD_ALL);
//                    System.exit(1);
                    //hilangin merah2 cuii VOID CODE
                }
            }

        }
    }

    public boolean lebihDari(double a,double b)
    {
        return (a>b) ? true : false;
    }
    


    public void jalankanBidak(MarkerModelNyID grid,MarkerModelNyID ptr1,MarkerModelNyID ptr2,StringBuffer stat) {
        indikatorPointer(grid, ptr1, stat);

//        geserBidak(grid.getBidak(), stat);
    }
    public Point2d konvPtr(Point3d t){
        Point2d p = new Point2d();
        p.setX(t.getX());
        p.setY(t.getY());
        return p;
    }
    public int translatePosisi(double max, double min, double ord){
        //ubah ke ordinat catur
        double range = Math.abs(max - min);
        double blok = range/8;
        int tempOrd =  (int) (ord+Math.abs(min)); //diubah nilai awal dari 0
        int pos =(int) (tempOrd/blok); //ilangin angka belakang koma
        return pos;
    }
    public Point4d hitBatas(Point2d pusatGrid, double jarak){
       Point4d p = new Point4d(pusatGrid.getX()+(jarak*100), pusatGrid.getY()+(jarak*100),
                pusatGrid.getX()-(jarak*100), pusatGrid.getY()-(jarak*100));
       return p;
    }
    public boolean isOcclusion(Point2d ptr, Point4d batas){
        double a = ptr.getX();
        double b = ptr.getY();
        double maxA = batas.getX();
        double maxB = batas.getY();
        double minA = batas.getZ();
        double minB = batas.getW();
        return((lebihDari(a, minA)&&lebihDari(maxA, a)&&lebihDari(b, minB)&&lebihDari(maxB, b))==true) ? true : false;
    }

}
